/**
  ******************************************************************************
  * @file    sym32l010_hal_rtc.h
  * @author  AE Team
  * @version 1.0.3
  * @date    2024-05-28
  * @brief   Header file of RTC HAL module.
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 SIYIMicro.
  * All rights reserved.</center></h2>
  *
  *
  ******************************************************************************
  */


/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SYM32L010_HAL_RTC_H
#define __SYM32L010_HAL_RTC_H

#ifdef __cplusplus
extern "C" {
#endif


/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include "sym32l010_hal_def.h"


/******************************************************************************/
/* Global type definitions                                                    */
/******************************************************************************/
/* 计时时制 -------------------------------------------------------------------*/
typedef enum
{
    RTC_HOUR_12H               = (0x0UL << RTC_CR0_H24_Pos),          // 12小时制
    RTC_HOUR_24H               = (0x1UL << RTC_CR0_H24_Pos)           // 24小时制
} RTC_HourModeTypeDef;

/* 计时时钟RTCCLK来源 ---------------------------------------------------------*/
typedef enum
{
    RTC_CLKSRC_LSE             = (0x0UL << RTC_CR1_SOURCE_Pos),       // RTCCLK = LSE
    RTC_CLKSRC_HSE             = (0x1UL << RTC_CR1_SOURCE_Pos),       // RTCCLK = HSE
    RTC_CLKSRC_LSI             = (0x2UL << RTC_CR1_SOURCE_Pos),       // RTCCLK = LSI
    RTC_CLKSRC_HSIOSC          = (0x3UL << RTC_CR1_SOURCE_Pos)        // RTCCLK = HSIOSC
} RTC_ClockSourceTypeDef;

/* 定时周期 -------------------------------------------------------------------*/
typedef enum
{
    RTC_INTERVAL_NONE          = (0x0UL << RTC_CR0_INTERVAL_Pos),     // 无周期性定时
    RTC_INTERVAL_HALFSECOND    = (0x1UL << RTC_CR0_INTERVAL_Pos),     // 周期性定时 = 0.5秒
    RTC_INTERVAL_SECOND        = (0x2UL << RTC_CR0_INTERVAL_Pos),     // 周期性定时 = 1秒
    RTC_INTERVAL_MINUTE        = (0x3UL << RTC_CR0_INTERVAL_Pos),     // 周期性定时 = 1分
    RTC_INTERVAL_HOUR          = (0x4UL << RTC_CR0_INTERVAL_Pos),     // 周期性定时 = 1小时
    RTC_INTERVAL_DAY           = (0x5UL << RTC_CR0_INTERVAL_Pos),     // 周期性定时 = 1天
    RTC_INTERVAL_MONTH         = (0x6UL << RTC_CR0_INTERVAL_Pos)      // 周期性定时 = 1月
} RTC_IntervalTypeDef;

/* 闹钟小时位屏蔽控制 ----------------------------------------------------------*/
typedef enum
{
    RTC_ALARM_HOUR_CHECK       = (0UL),                               // 闹钟需要检查小时位计数
    RTC_ALARM_HOUR_UNCHECK     = (RTC_ALARMA_HOUR_Msk)                // 闹钟与小时计数无关
} RTC_HourCheckTypeDef;

/* 闹钟分钟位屏蔽控制 ----------------------------------------------------------*/
typedef enum
{
    RTC_ALARM_MINUTE_CHECK     = (0UL),                               // 闹钟需要检查分钟位计数
    RTC_ALARM_MINUTE_UNCHECK   = (RTC_ALARMA_MINUTE_Msk)              // 闹钟与分钟计数无关
} RTC_MinuteCheckTypeDef;

/* 闹钟秒钟位屏蔽控制 ----------------------------------------------------------*/
typedef enum
{
    RTC_ALARM_SECOND_CHECK     = (0UL),                               // 闹钟需要检查秒位计数
    RTC_ALARM_SECOND_UNCHECK   = (RTC_ALARMA_SECOND_Msk)              // 闹钟与秒计数无关
} RTC_SecondCheckTypeDef;

/* 唤醒定时器计数时钟来源 ------------------------------------------------------*/
typedef enum
{
    RTC_AWT_CLKSRC_RTCCLKD     = (0UL << RTC_CR2_AWTSRC_Pos),
    RTC_AWT_CLKSRC_TICKCLK     = (1UL << RTC_CR2_AWTSRC_Pos)          // TCLKCLK = RTCCLKD / 16384
} RTC_AWTClkSourceTypeDef;

/* 唤醒定时器计数时钟预分频 ----------------------------------------------------*/
typedef enum
{
    RTC_AWT_PRS_2              = (0UL << RTC_CR2_AWTPRS_Pos),         // 2 分频
    RTC_AWT_PRS_4              = (1UL << RTC_CR2_AWTPRS_Pos),         // 4 分频
    RTC_AWT_PRS_8              = (2UL << RTC_CR2_AWTPRS_Pos),         // 8 分频
    RTC_AWT_PRS_16             = (3UL << RTC_CR2_AWTPRS_Pos)          // 16 分频
} RTC_AWTPrescalerTypeDef;

/* 入侵检测 -------------------------------------------------------------------*/
typedef enum
{
    RTC_TAMPEDGE_RISE          = (0UL << RTC_CR2_TAMPEDGE_Pos),       // 上升沿记录当前时间
    RTC_TAMPEDGE_FALL          = (1UL << RTC_CR2_TAMPEDGE_Pos)        // 下降沿记录当前时间
} RTC_TampedgeTypeDef;

/* 输出1Hz信号的补偿方式 -------------------------------------------------------*/
typedef enum
{
    RTC_1HZ_RTCCLK             = (1UL)                                // 输出采用RTCCLK补偿1Hz信号
} RTC_CompenSourceTypeDef;

/* 时钟误差补偿周期 -----------------------------------------------------------*/
typedef enum
{
    RTC_COMPEN_PERIOD_32S      = (0x0UL << RTC_COMPCFR1_PERIOD_Pos),  // 补偿周期为32秒
    RTC_COMPEN_PERIOD_128S     = (0x1UL << RTC_COMPCFR1_PERIOD_Pos),  // 补偿周期为128秒
    RTC_COMPEN_PERIOD_256S     = (0x2UL << RTC_COMPCFR1_PERIOD_Pos)   // 补偿周期为256秒
} RTC_CompenPeriodTypeDef;

/* 时钟误差补偿方向 -----------------------------------------------------------*/
typedef enum
{
    RTC_COMPEN_SIGN_INC        = (0x0UL << RTC_COMPCFR1_SIGN_Pos),    // LSE频率大于32768时，选择此项
    RTC_COMPEN_SIGN_DEC        = (0x1UL << RTC_COMPCFR1_SIGN_Pos)     // LSE频率小于32768时，选择此项
} RTC_CompenSignTypeDef;

/* RTC 日历初始化 -------------------------------------------------------------*/
typedef struct
{
    RTC_HourModeTypeDef    HourMode;                                  // 计时时制
    RTC_ClockSourceTypeDef ClockSource;                               // 计时时钟RTCCLK来源

    uint32_t               Year;                                      // 年 0x00 - 0x99  BCD
    uint32_t               Month;                                     // 月 0x01 - 0x12  BCD
    uint32_t               Day;                                       // 日 0x01 - 0x31  BCD
    uint32_t               Week;                                      // 星期 0x00 - 0x06  BCD  0=Sunday, 1-6=Monday-saturday

    uint32_t               Hour;                                      // 时 0x00 - 0x23  BCD
    uint32_t               Minute;                                    // 分 0x00 - 0x59  BCD
    uint32_t               Second;                                    // 秒 0x00 - 0x59  BCD

    RTC_IntervalTypeDef    Interval;                                  // 定时周期
} RTC_Calendar_InitTypeDef;

/* RTC 日历 ------------------------------------------------------------------*/
typedef struct
{
    uint32_t Year;                                                    // 年 0x00 - 0x99  BCD
    uint32_t Month;                                                   // 月 0x01 - 0x12  BCD
    uint32_t Day;                                                     // 日 0x01 - 0x31  BCD
    uint32_t Week;                                                    // 星期 0x00 - 0x06  BCD  0=Sunday, 1-6=Monday-saturday

    uint32_t Hour;                                                    // 时 0x00 - 0x23  BCD
    uint32_t Minute;                                                  // 分 0x00 - 0x59  BCD
    uint32_t Second;                                                  // 秒 0x00 - 0x59  BCD
} RTC_CalendarDateTimeTypeDef;

/* RTC 日期 ------------------------------------------------------------------*/
typedef struct
{
    uint32_t Year;                                                    // 年 0x00 - 0x99  BCD
    uint32_t Month;                                                   // 月 0x01 - 0x12  BCD
    uint32_t Day;                                                     // 日 0x01 - 0x31  BCD
    uint32_t Week;                                                    // 星期 0x00 - 0x06  BCD  0=Sunday, 1-6=Monday-saturday
} RTC_CalendarDateTypeDef;

/* RTC 时间 ------------------------------------------------------------------*/
typedef struct
{
    uint32_t Hour;                                                    // 时 0x00 - 0x23  BCD
    uint32_t Minute;                                                  // 分 0x00 - 0x59  BCD
    uint32_t Second;                                                  // 秒 0x00 - 0x59  BCD
} RTC_CalendarTimeTypeDef;

/* RTC 闹钟 ------------------------------------------------------------------*/
typedef struct
{
    uint32_t                AlarmWeek;                                // 闹钟星期使能
    uint32_t                Hour;                                     // 0x00 - 0x23  BCD
    uint32_t                Minute;                                   // 0x00 - 0x59  BCD
    uint32_t                Second;                                   // 0x00 - 0x59  BCD
    RTC_HourCheckTypeDef    HourCheck;                                // 闹钟小时位屏蔽控制
    RTC_MinuteCheckTypeDef  MinuteCheck;                              // 闹钟分钟位屏蔽控制
    RTC_SecondCheckTypeDef  SecondCheck;                              // 闹钟秒钟位屏蔽控制
} RTC_Alarm_InitTypeDef;

/* RTC 唤醒定时器 -------------------------------------------------------------*/
typedef struct
{
    RTC_AWTClkSourceTypeDef ClkSource;                                // 唤醒定时器计数时钟来源
    RTC_AWTPrescalerTypeDef Prescaler;                                // 唤醒定时器计数时钟预分频
    uint16_t Reload;                                                  // 0 ... 65535，溢出周期为 Reload+1
} RTC_AWT_InitTypeDef;


typedef struct
{
    RTC_ClockSourceTypeDef  ClkSrc;                                   // RTC时钟源选择
    uint32_t                ClkSrcFreq;                               // RTC时钟源频率 (单位：Hz)
    uint8_t                 Psc1;                                     // RTC时钟一级分频 分频后时钟频率不能超过1M
    uint32_t                Psc2;                                     // RTC时钟二级分频
} RTC_ClkCfg_InitTypeDef;


/******************************************************************************/
/* Global pre-processor symbols/macros ('#define')                            */
/******************************************************************************/
/* 闹钟星期使能 ---------------------------------------------------------------*/
#define RTC_ALARMWEEK_Sunday     (0x01UL << RTC_ALARMA_WEEKEN_Pos)    // 星期天
#define RTC_ALARMWEEK_Monday     (0x02UL << RTC_ALARMA_WEEKEN_Pos)    // 星期一
#define RTC_ALARMWEEK_Tuesday    (0x04UL << RTC_ALARMA_WEEKEN_Pos)    // 星期二
#define RTC_ALARMWEEK_Wednesday  (0x08UL << RTC_ALARMA_WEEKEN_Pos)    // 星期三
#define RTC_ALARMWEEK_Thursday   (0x10UL << RTC_ALARMA_WEEKEN_Pos)    // 星期四
#define RTC_ALARMWEEK_Friday     (0x20UL << RTC_ALARMA_WEEKEN_Pos)    // 星期五
#define RTC_ALARMWEEK_Saturday   (0x40UL << RTC_ALARMA_WEEKEN_Pos)    // 星期六
#define RTC_ALARMWEEK_Weekdays   (0x3EUL << RTC_ALARMA_WEEKEN_Pos)    // 工作日
#define RTC_ALARMWEEK_Weekends   (0x41UL << RTC_ALARMA_WEEKEN_Pos)    // 周  末
#define RTC_ALARMWEEK_Everyday   (0x7FUL << RTC_ALARMA_WEEKEN_Pos)    // 每一天

/* IER -----------------------------------------------------------------------*/
#define RTC_IT_SOURCE_INTERVAL    (RTC_IER_INTERVAL_Msk)              // 周期性定时完成
#define RTC_IT_SOURCE_TAMPOV      (RTC_IER_TAMPOV_Msk)                // 时间戳溢出
#define RTC_IT_SOURCE_TAMP        (RTC_IER_TAMP_Msk)                  // 时间戳事件
#define RTC_IT_SOURCE_AWTIMER     (RTC_IER_AWTIMER_Msk)               // 唤醒定时器定时完成
#define RTC_IT_SOURCE_ALARMB      (RTC_IER_ALARMB_Msk)                // 闹钟B匹配
#define RTC_IT_SOURCE_ALARMA      (RTC_IER_ALARMA_Msk)                // 闹钟A匹配

/* ISR -----------------------------------------------------------------------*/
#define RTC_IT_FLAG_INTERVAL      (RTC_ISR_INTERVAL_Msk)              // 周期性定时完成
#define RTC_IT_FLAG_TAMPOV        (RTC_ISR_TAMPOV_Msk)                // 时间戳溢出
#define RTC_IT_FLAG_TAMP          (RTC_ISR_TAMP_Msk)                  // 时间戳事件
#define RTC_IT_FLAG_AWTIMER       (RTC_ISR_AWTIMER_Msk)               // 唤醒定时器定时完成
#define RTC_IT_FLAG_ALARMB        (RTC_ISR_ALARMB_Msk)                // 闹钟B匹配
#define RTC_IT_FLAG_ALARMA        (RTC_ISR_ALARMA_Msk)                // 闹钟A匹配


/******************************************************************************/
/* Global macro function                                                      */
/******************************************************************************/
/**
  * @brief  获取 RTC 中断触发源
  * @param  ITSOURCE: RTC中断触发源
  *                   @arg RTC_IT_SOURCE_INTERVAL
  *                   @arg RTC_IT_SOURCE_TAMPOV
  *                   @arg RTC_IT_SOURCE_TAMP
  *                   @arg RTC_IT_SOURCE_AWTIMER
  *                   @arg RTC_IT_SOURCE_ALARMB
  *                   @arg RTC_IT_SOURCE_ALARMA
  * @retval
  */
#define HAL_RTC_GET_IT_SOURCE(ITSOURCE)  (SYM_RTC->IER & (uint32_t)(ITSOURCE))

/**
  * @brief  获取 RTC 中断标志
  * @param  ITSOURCE: TRC中断标志
  *                   @arg RTC_IT_FLAG_INTERVAL
  *                   @arg RTC_IT_FLAG_TAMPOV
  *                   @arg RTC_IT_FLAG_TAMP
  *                   @arg RTC_IT_FLAG_AWTIMER
  *                   @arg RTC_IT_FLAG_ALARMB
  *                   @arg RTC_IT_FLAG_ALARMA
  * @retval
  */
#define HAL_RTC_GET_FLAG(FLAG)           (SYM_RTC->ISR & (FLAG))

/**
  * @brief  清除 RTC 中断标志
  * @param  ITSOURCE: TRC中断标志
  *                   @arg RTC_IT_FLAG_INTERVAL
  *                   @arg RTC_IT_FLAG_TAMPOV
  *                   @arg RTC_IT_FLAG_TAMP
  *                   @arg RTC_IT_FLAG_AWTIMER
  *                   @arg RTC_IT_FLAG_ALARMB
  *                   @arg RTC_IT_FLAG_ALARMA
  * @retval
  */
#define HAL_RTC_CLR_FLAG(FLAG)           (SYM_RTC->ICR = ~((uint32_t)(FLAG)))


/******************************************************************************/
/* Exported variables ('extern', definition in C source)                      */
/******************************************************************************/


/******************************************************************************/
/* Global function prototypes ('extern', definition in C source)              */
/******************************************************************************/
void HAL_RTC_Regs_Unlock(void);
void HAL_RTC_Regs_Lock(void);

float HAL_RTC_GetSubSecond(void);
void HAL_RTC_Calendar_Start(void);
void HAL_RTC_Calendar_Stop(void);
void HAL_RTC_Calendar_Init(RTC_Calendar_InitTypeDef *InitStruct);
void HAL_RTC_Calendar_SetDateTime(RTC_CalendarDateTimeTypeDef *pDateTime);
void HAL_RTC_Calendar_SetDate(RTC_CalendarDateTypeDef *pDate);
void HAL_RTC_Calendar_SetTime(RTC_CalendarTimeTypeDef *pTime);
void HAL_RTC_Calendar_GetDateTime(RTC_CalendarDateTimeTypeDef *pDateTime);
void HAL_RTC_Calendar_GetDate(RTC_CalendarDateTypeDef *pDate);
void HAL_RTC_Calendar_GetTime(RTC_CalendarTimeTypeDef *pTime);

void HAL_RTC_AlarmA_Config(RTC_Alarm_InitTypeDef *pAlarm);
void HAL_RTC_AlarmB_Config(RTC_Alarm_InitTypeDef *pAlarm);
void HAL_RTC_AlarmA_Enable(void);
void HAL_RTC_AlarmB_Enable(void);
void HAL_RTC_AlarmA_Disable(void);
void HAL_RTC_AlarmB_Disable(void);

void HAL_RTC_AWT_Start(void);
void HAL_RTC_AWT_Stop(void);
void HAL_RTC_AWT_Init(RTC_AWT_InitTypeDef *InitStruct);
uint16_t HAL_RTC_AWT_GetCnt(void);

void HAL_RTC_TAMP_Disable(void);
void HAL_RTC_TAMP_Enable(RTC_TampedgeTypeDef TampEdge);
void HAL_RTC_TAMP_GetDateTime(RTC_CalendarDateTimeTypeDef *pDateTime);

void HAL_RTC_Compen_Enable(void);
void HAL_RTC_Compen_Disable(void);
void HAL_RTC_Compen_Config(RTC_CompenPeriodTypeDef Period,
                                  RTC_CompenSignTypeDef Sign, uint16_t Value);

void HAL_RTC_ENABLE_IT(uint32_t ITSource);
void HAL_RTC_DISABLE_IT(uint32_t ITSource);

void HAL_RTC_DeInit(void);
HAL_StatusTypeDef  HAL_RTCCLK_Config(RTC_ClkCfg_InitTypeDef *InitStruct);
void HAL_RTC_1Hz_Config(RTC_CompenSourceTypeDef Rtc1HzCfg);
void HAL_RTC_Time_AddSeconds(RTC_CalendarTimeTypeDef *pCurTime, uint16_t AddSecs);


#ifdef __cplusplus
}
#endif

#endif /* __SYM32L010_HAL_RTC_H */


/************************ (C) COPYRIGHT SIYIMicro *****END OF FILE*************/
